home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / frontend_implementation / HTMLDisplay.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  7.0 KB  |  221 lines

  1. # Miro - an RSS based video player application
  2. # Copyright (C) 2005-2007 Participatory Culture Foundation
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  17.  
  18. import threading
  19. import socket
  20. import re
  21. import xhtmltools
  22. import time
  23. import errno
  24. import os
  25.  
  26. import app
  27. import config
  28. import download_utils
  29. import tempfile
  30. import os
  31. import platformutils
  32. import prefs
  33. import frontend
  34. from frontend_implementation import urlcallbacks
  35.  
  36. tempdir = os.path.join(tempfile.gettempdir(), config.get(prefs.SHORT_APP_NAME))
  37.  
  38. def getDTVAPICookie():
  39.     return None
  40. def getDTVAPIURL():
  41.     return None
  42.  
  43. pageFinishCallbacks = {}
  44. def runPageFinishCallback(area, url):
  45.     try:
  46.         callback = pageFinishCallbacks[area]
  47.     except KeyError:
  48.         return
  49.     else:
  50.         callback(url)
  51.  
  52. def deferUntilLoad(function):
  53.     def wrapper(self, *args):
  54.         if self.pageLoadFinised:
  55.             function(self, *args)
  56.         else:
  57.             self.deferedCalls.append((function, args))
  58.     return wrapper
  59.  
  60. def initTempDir():
  61.     if os.path.exists(tempdir):
  62.         # get rid of stale temp files
  63.         for child in os.listdir(tempdir):
  64.             try:
  65.                 os.unlink(os.path.join(tempdir, child))
  66.             except:
  67.                 pass
  68.     else:
  69.         os.mkdir(tempdir)
  70.  
  71. def makeFileUrl(path):
  72.     path = platformutils.osFilenameToFilenameType(path.replace("\\", "/"))
  73.     return "file:///" + platformutils.makeURLSafe(path)
  74.  
  75. def compareFileUrls(url1, url2):
  76.     if not url1.startswith("file://") or not url2.startswith("file://"):
  77.         return False
  78.     def normalize(url):
  79.         path = download_utils.getFileURLPath(url)
  80.         return os.path.normpath(platformutils.getLongPathName(path))
  81.     return normalize(url1) == normalize(url2)
  82.  
  83. class HTMLDisplay (app.Display):
  84.     "Selectable Display that shows a HTML document."
  85.  
  86.     def __init__(self, html, existingView=None, frameHint=None, areaHint=None,
  87.                  baseURL=None):
  88.         self.initialHTML = html
  89.         self.area = None
  90.         self.pageLoadFinised = False
  91.         self.deferedCalls = []
  92.         self.location = None
  93.         if baseURL == config.get(prefs.CHANNEL_GUIDE_URL):
  94.             self.removeTempFile = False
  95.         else:
  96.             self.removeTempFile = True
  97.  
  98.  
  99.     def setInitialHTML(self):
  100.         if not os.path.exists(tempdir):
  101.             os.mkdir(tempdir)
  102.         handle, location = tempfile.mkstemp('.html', dir=tempdir)
  103.         handle = os.fdopen(handle, "wt")
  104.         try:
  105.             handle.write(self.initialHTML)
  106.         finally:
  107.             handle.close()
  108.         self.location = os.path.abspath(location)
  109.         self.url = makeFileUrl(self.location)
  110.         urlcallbacks.installCallback(self.url, self.onURLLoad)
  111.         frontend.jsBridge.xulNavigateDisplay(self.area, self.url)
  112.  
  113.     def pageFinishCallback(self, url):
  114.         # make sure that the page that finished was our page, if we install
  115.         # enough HTMLDisplays in a short time, then the last HTMLDisplay can
  116.         # get callbacks for the earlier loads.
  117.         if url.startswith("file://") and compareFileUrls(url, self.url):
  118.             self.pageLoadFinised = True
  119.             for function, args in self.deferedCalls:
  120.                 function(self, *args)
  121.             if self.removeTempFile:
  122.                 try:
  123.                     os.unlink(self.location)
  124.                 except:
  125.                     pass
  126.  
  127.     def setArea(self, area):
  128.         self.area = area
  129.         self.pageLoadFinised = False
  130.         pageFinishCallbacks[self.area] = self.pageFinishCallback
  131.         self.setInitialHTML()
  132.  
  133.     def removedFromArea(self):
  134.         try:
  135.             del pageFinishCallbacks[self.area]
  136.         except KeyError:
  137.             pass
  138.         self.area = None
  139.  
  140.     @deferUntilLoad
  141.     def navigateToFragment(self, fragment):
  142.         fullUrl = "%s#%s" % (self.url, fragment)
  143.         frontend.jsBridge.xulNavigateDisplay(self.area, fullUrl)
  144.  
  145.     @deferUntilLoad
  146.     def addItemAtEnd(self, xml, id):
  147.         frontend.jsBridge.xulAddElementAtEnd(self.area, xml, id)
  148.  
  149.     @deferUntilLoad
  150.     def addItemBefore(self, xml, id):
  151.         frontend.jsBridge.xulAddElementBefore(self.area, xml, id)
  152.     
  153.     @deferUntilLoad
  154.     def removeItem(self, id):
  155.         frontend.jsBridge.xulRemoveElement(self.area, id)
  156.     
  157.     @deferUntilLoad
  158.     def removeItems(self, ids):
  159.         for id in ids:
  160.             frontend.jsBridge.xulRemoveElement(self.area, id)
  161.     
  162.     @deferUntilLoad
  163.     def changeItem(self, *args):
  164.         self._doChangeItem(*args)
  165.  
  166.     @deferUntilLoad
  167.     def changeItems(self, listOfArgs):
  168.         for args in listOfArgs:
  169.             self._doChangeItem(*args)
  170.  
  171.     def _doChangeItem(self, id, xml, changeHint):
  172.         if changeHint is None or changeHint.changedInnerHTML is not None:
  173.             frontend.jsBridge.xulChangeElement(self.area, id, xml)
  174.         else:
  175.             for name, value in changeHint.changedAttributes.items():
  176.                 if value is not None:
  177.                     frontend.jsBridge.xulChangeAttribute(self.area, id, name,
  178.                             value)
  179.                 else:
  180.                     frontend.jsBridge.xulRemoveAttribute(self.area, id, name)
  181.  
  182.     @deferUntilLoad
  183.     def hideItem(self, id):
  184.         frontend.jsBridge.xulHideElement(self.area, id)
  185.         
  186.     @deferUntilLoad
  187.     def showItem(self, id):
  188.         frontend.jsBridge.xulShowElement(self.area, id)
  189.  
  190.     def onDeselected(self, frame):
  191.         pass
  192.  
  193.     def getEventCookie(self):
  194.         return ''
  195.  
  196.     def getDTVPlatformName(self):
  197.         return 'xul'
  198.  
  199.     def getBodyTagExtra(self):
  200.         return ''
  201.  
  202.     def onURLLoad(self, url):
  203.         """Called when this HTML browser attempts to load a URL (either
  204.         through user action or Javascript.) The URL is provided as a
  205.         string. Return true to allow the URL to load, or false to cancel
  206.         the load (for example, because it was a magic URL that marks
  207.         an item to be downloaded.) Implementation in HTMLDisplay always
  208.         returns true; override in a subclass to implement special
  209.         behavior."""
  210.         # For overriding
  211.         return True
  212.  
  213.     def unlink(self):
  214.         try:
  215.             urlcallbacks.removeCallback(self.location)
  216.         except KeyError:
  217.             pass
  218.  
  219.     def __del__(self):
  220.         self.unlink()
  221.